/*
 * ArenaTicketMain - Venda de Bilhetes Eletronicos para Espetaculos (Arena Entretenimento S.A.)
 * Util.java
 * ©2006
 */
package br.unicamp.ic.inf312.arena.util;

import br.unicamp.ic.inf312.framework.util.TipoInvalidoException;

import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * @author inf312
 */
public class Util {
	private Util() {}

	private static ISaidaPadrao saidaPadrao;
	
	//TODO: Alteracao para a ativ. 11
	public static final byte REF_DIFERENCA_HORAS = 1;
	public static final byte REF_DIFERENCA_DIAS  = 2;
	public static final byte REF_DIFERENCA_MESES = 3;
	public static final byte REF_DIFERENCA_ANOS  = 4;
	

	/**
	 * @uml.property  name="saidaPadrao"
	 */
	public static void setSaidaPadrao(ISaidaPadrao saidaPadrao) {
		Util.saidaPadrao = saidaPadrao;
	}

	public static void imprimir(Object msg) {
		// Implementacao do logging
		// Ponto unico de alteracao
		System.out.println(msg);//logging de erro no console do IDE
	}

	public static void imprimir(String msg) {
		// Implementacao do logging
		// Ponto unico de alteracao
		saidaPadrao.mostrarMensagem(msg, true);//apresentar MSG na GUI
	}

	public static void limparTela() {
		// Implementacao do logging
		// Ponto unico de alteracao
		// System.out.println(msg);
		saidaPadrao.limpar();
	}


	/**
	 * 
	 * @param str
	 * @return int
	 * @throws TipoInvalidoException
	 */
	public static int stringToInt(String str) throws TipoInvalidoException {
		int retorno = -1;
		try {
			retorno = Integer.parseInt(str);
		} catch (NumberFormatException e) {
			throw new TipoInvalidoException("Tipo inteiro invalido!");
		}
		return retorno;
	}

	/**
	 *
	 * @param data
	 * @param formato (se null, usa o formato dd/MM/yyyy por padrao)
	 *
	 * @return String
	 * 
	 */
	public static String obterDataNoFormato(Date data, String formato) {
		SimpleDateFormat sdf = null;
		if (formato == null) {
			sdf = new SimpleDateFormat("dd/MM/yyyy");
		} else {
			sdf = new SimpleDateFormat(formato);
		}
		return ( sdf.format(data) );
	}

	/**
	 *
	 * @param data
	 * @return String ("dd-MM-yyyy")
	 */
	public static String obterDataFormatada(Date data) {
		SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
		return ( sdf.format(data) );
	}
	
	/**
	 * 
	 * @param data
	 * @return String ("HH:mm:ss")
	 */
	public static String obterHoraFormatada(Time hora) {
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		return ( sdf.format(hora) );
	}

	/**
	 *
	 * @param dia
	 * @param mes
	 * @param ano
	 *
	 * @return Date
	 *
	 */
	public static Date gerarData(int dia, int mes, int ano) {
		Calendar calendar = Calendar.getInstance();

		// normalizar java.util.Date
		calendar.setTime(new Date());
		calendar.set(Calendar.DAY_OF_MONTH, dia);
		calendar.set(Calendar.MONTH, mes - 1);
		calendar.set(Calendar.YEAR, ano);

		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);		

		return ( calendar.getTime() );
	}

	/**
	 * 
	 * @param dia
	 * @param mes
	 * @param ano
	 * @return String (yyyy-MM-dd) --> formato para comparar com datas na base de dados
	 */
	public static String gerarDataNoFormatoString(int dia, int mes, int ano) {
		Date data = gerarData(dia, mes, ano);
		//TODO: Alteracao para a ativ. 4
		return gerarDataNoFormatoString(data);
	}
	
	//TODO: Alteracao para a ativ. 4
	public static String gerarDataNoFormatoString( Date data )
	{
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		return ( sdf.format(data) );
	}
	
	//TODO: Alteracao para a ativ. 4
	public static Date avancarUltimoDiaMes( Date data )
	{
		// cria um objeto calendario
		Calendar calendario = Calendar.getInstance();
		
		// atribui a data
		calendario.setTime(data);
		
		// obtem o ultimo dia para esta data
		int ultimoDia = calendario.getActualMaximum(Calendar.DAY_OF_MONTH);
		
		// avanca a data para o ultimo dia do mes
		calendario.set(Calendar.DAY_OF_MONTH, ultimoDia);
		
		// retorna a data avancada
		return ( calendario.getTime());
	}
	
	//TODO: Alteracao para a ativ. 4
	public static Date retrocederPrimeiroDiaMes( Date data )
	{
		// cria um objeto calendario
		Calendar calendario = Calendar.getInstance();
		
		// atribui a data
		calendario.setTime(data);
		
		// retrocede a data para o primeiro dia do mes
		calendario.set(Calendar.DAY_OF_MONTH, 1);
		
		// retorna a data retrocedida
		return ( calendario.getTime());
	}
	
	//TODO: Alteracao para a ativ. 11
	public static long obterDiferencaEntreDatas( Date data1, Date data2, int referencia )
	{
		// obtem a diferenca das datas em milisegundos
		long tempo = data1.getTime() - data2.getTime();
		
		// normaliza para minutos
		tempo /= 60000;
		
		// verifica a opcao de referencia
		switch ( referencia )
		{
			case Util.REF_DIFERENCA_HORAS:
				return ( tempo / 60 );
				
			case Util.REF_DIFERENCA_DIAS:
				return ( tempo / 60 / 24 );
				
			case Util.REF_DIFERENCA_MESES:
				return ( tempo / 60 / 24 / 30 );
				
			default:
				return ( tempo / 60 / 24 / 30 / 12 );
		}
	}
	
	//TODO: Alteracao para a ativ. 11
	public static Date normalizarData( Date data, Time horario )
	{
		// obtem um calendario p/ o horario
		Calendar calHorario = Calendar.getInstance();
		
		// obtem um calendario p/ a data
		Calendar calData = Calendar.getInstance();
		
		// atribui o horario (hh,mm,ss)
		calHorario.setTimeInMillis( horario.getTime() );
		
		// atribui a data (d,m,a)
		calData.setTimeInMillis( data.getTime() );
		
		// ajusta o horario a data
		calData.set( Calendar.HOUR_OF_DAY, calHorario.get( Calendar.HOUR_OF_DAY ) );
		calData.set( Calendar.MINUTE, calHorario.get( Calendar.MINUTE ) );
		calData.set( Calendar.SECOND, calHorario.get( Calendar.SECOND ) );
		
		// retorna a data normalizada (d,m,a,hh,mm,ss)
		return ( calData.getTime() );
	}
	
	/**
	 * 
	 * @param strDia
	 * @param strMes
	 * @param strAno
	 * 
	 * @return String  (yyyy-MM-dd) --> formato para comparar com datas na base de dados
	 */
	public static String gerarDataNoFormatoString(String strDia, String strMes, String strAno) {
		int dia = 0;
		if (strDia != null && strDia.length() > 1) {
			dia = Integer.valueOf(strDia).intValue();
		}

		int mes = 0;
		if (strMes != null && strMes.length() > 1) {
			mes = Integer.valueOf( strMes ).intValue();
		}

		int ano = 0;
		if (strAno != null && strAno.length() > 1) {
			ano = Integer.valueOf( strAno ).intValue();
		}

		return gerarDataNoFormatoString(dia, mes, ano);
	}

	/**
	 *
	 * @param horas (int)
	 * @param minutos (int)
	 *
	 * @return horario da sessao (java.sql.Time)
	 *
	 */
	public static Time gerarHorarioSessao(int horas, int minutos) {
		Calendar calendar = Calendar.getInstance();
		//
		calendar.setTime(new Date());
		calendar.set(Calendar.HOUR, horas);
		calendar.set(Calendar.MINUTE, minutos);
		calendar.set(Calendar.SECOND, 00);
		//
		return (new Time(calendar.getTimeInMillis()));
	}

	/**
	 * 
	 * @param horas
	 * @param minutos
	 * @return
	 * Time
	 */
	public static Time gerarDuracaoSessao(int horas, int minutos) {
		return gerarHorarioSessao(horas, minutos);
	}

	/**
	 *
	 * @param dataCorrente (java.util.Date)
	 *
	 * @return horario da sessao (java.sql.Time)
	 *
	 */
	public static Time obterHoraCorrente(Date dataCorrente) {
		Calendar calendar = Calendar.getInstance();
		//
		calendar.setTime(dataCorrente);
		return (new Time(calendar.getTimeInMillis()));
	}

	/**
	 *
	 * @param  dataCorrente (java.util.Date)
	 * @param  dataBanco    (java.sql.Date)
	 *
	 * @return boolean
	 *
	 */
	public static boolean isMesmaData(Date dataCorrente, java.sql.Date dataBanco) {
		Calendar calendar = Calendar.getInstance();

		// normalizar java.util.Date
		calendar.setTime(dataCorrente);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);

		return ( dataBanco.equals( calendar.getTime() ) );
	}
}